home *** CD-ROM | disk | FTP | other *** search
/ Trading on the Edge / Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin / pc / mac_file / vendor_d / neuralwa / nw2v50 / pattern.c < prev    next >
Text File  |  1993-08-23  |  29KB  |  951 lines

  1. /*09-Feb-89  (pattern.c)  Pattern I/O routine */
  2. /* 13Apr90 -emb -chgs for Zortech v2.0 compatibility */
  3.  
  4. /************************************************************************
  5.  * Copyright(C) 1987-1992 NeuralWare Inc                                *
  6.  * Penn Center West, IV-227, Pittsburgh, PA 15276                       *
  7.  * Telephone: (412) 787-8222    FAX: (412) 787-8220                     *
  8.  *                                                                      *
  9.  * All rights reserved.  No part of this program may be reproduced,     *
  10.  * stored in a retrieval system, or transmitted, in any form or by any  *
  11.  * means, electronic, mechanical, photocopying, recording or otherwise  *
  12.  * without the prior written permission of the copyright owner,         *
  13.  * NeuralWare, Inc.                                                     *
  14.  *                                                                      *
  15.  *                          PROPRIETARY NOTICE                          *
  16.  *                                                                      *
  17.  * This document is the property of NeuralWare, Inc. and contains       *
  18.  * trade-secrets and other proprietary information.  The information    *
  19.  * herein is reserved as proprietary to NeuralWare, and is not to be    *
  20.  * published, reproduced, copied, disclosed, used, or reverse           *
  21.  * engineered without the express written consent of a duly authorized  *
  22.  * representative of NeuralWare.                                        *
  23.  ************************************************************************
  24.  */
  25.  
  26.  
  27. #include "userutl.h"
  28. #include <string.h>
  29. #ifndef SUN
  30. #ifndef DLC
  31. #include <stdlib.h>
  32. #endif
  33. #endif
  34.  
  35. #ifdef MAC
  36. #include  "macuio.redef"
  37. #endif
  38.  
  39. /************************************************************************
  40.  *
  41.  *  This is a general purpose pattern I/O routine for use with
  42.  *  any network type.
  43.  *
  44.  *  Options:
  45.  *
  46.  *  ATTENTION I/O:  This allows the user to create a file of
  47.  *      character patterns and their associated
  48.  *      ASCII code. This file is written in .nna
  49.  *      format and can be used either for file I/O
  50.  *      or for userio learning. The user
  51.  *      is prompted for file name (.nna extension
  52.  *      assumed), and is given the option of writing or
  53.  *      appending the file. The user is provided with
  54.  *      a grid in which to draw patterns. On entering
  55.  *      a pattern, the user is prompted to enter, from
  56.  *      the keyboard, the character that the pattern
  57.  *      depicts. The file is closed on quitting.
  58.  *
  59.  *  REWIND:   If a file is open it is rewound.
  60.  *
  61.  ************************************************************************
  62.  */
  63.  
  64.  
  65. /* grid definitions */
  66. static long n_across[2], n_down[2], n_inputs[2], tot_n_inputs;
  67.  
  68. #define N_ACR_MIN 1
  69. #define N_ACR_MAX 32
  70. #define N_ACC_DEF 6
  71. #define N_DWN_MIN 1
  72. #define N_DWN_MAX 32
  73. #define N_DWN_DEF 8
  74.  
  75. /* window coordinates - initialized in usrIO( ) */
  76. static int  wxstrt[4], wystrt[4], wxend[4], wyend[4];
  77.  
  78. typedef struct _grid {
  79.   unsigned char gr_key;   /* window key for grid */
  80.   unsigned char gr_flag;  /* grid flag */
  81.   int  gr_xoff, gr_yoff;  /* x,y offset from window origin */
  82.   int  gr_nx, gr_ny;    /* # pixels in x, y directions */
  83.   int  gr_pxx, gr_pxy;  /* size of a grid pixel */
  84.   int  gr_color[3];   /* color of lines and pixels */
  85. #define    GR_OFF   0 /* off color index */
  86. #define    GR_ON    1 /* on color index */
  87. #define    GR_LINE  2 /* line color index */
  88.   float *gr_data;   /* data for grid */
  89. } GRID;
  90.  
  91. static  GRID  ip_grid[2] = { 0 }; /* Input Grids */
  92.  
  93. /* Local menu definitions */
  94.  
  95. #define CR_SCROLL 0
  96. #define CR_SEEK   1
  97. #define CR_ENTER  2
  98. #define CR_QUIT   3
  99. #define CR_AUTO   4
  100.  
  101. #define NULL_STR    0
  102.  
  103. static GMENU_ITEM  PMenuList[] = {  /* Menu list */
  104.     { CR_SCROLL, NULL_STR, NULL_STR },
  105.     { CR_SEEK,   NULL_STR, NULL_STR },
  106.     { CR_ENTER,  NULL_STR, NULL_STR },
  107.     { CR_QUIT,   NULL_STR, NULL_STR },
  108.     { CR_AUTO,   NULL_STR, NULL_STR }
  109. };
  110. static GMENU  AIOMenu  = {  /* Attention I/O menu */
  111.   0,
  112.   4,        /* # items */
  113.   3,        /* key */
  114.   0x0000
  115. };
  116. static GMENU  LrnMenu  = {  /* Attention I/O menu */
  117.   0,
  118.   5,        /* # items */
  119.   3,        /* key */
  120.   0x0000
  121. };
  122.  
  123. /* File definitions */
  124. static  char  filename[13];
  125. static  char  filenroot[9];
  126. static  int curr_pattern, n_patterns;   /* pattern index, # patterns */
  127. #define MAX_N_PATTERNS  200
  128. static  long  *filepos; /* Array of file positions */
  129. static  int   *shuffle_array;/* Index into shuffle array */
  130. static  int shufflex =  0;    /* Shuffle Index */
  131. #define MAX_STR 78        /* For reading from file */
  132. static  char  fbuf[MAX_STR + 1];    /* buffer for file i/o */
  133. static  FILE  *fp = 0;      /* File pointer */
  134. static  float *fdata;     /* file data */
  135. /* Network parameters */
  136. static  int   nlayp, ninp, noutp, ltype;  /* Network parameters */
  137. static  char  *csp, *netnp;     /* Network pointers*/
  138. static  int   BamFlag = 0;      /* Flags BAM control strat */
  139. /* Graphics parameters */
  140. static  int   xsize, ysize, ncolor, chrx, chry; /* graphics parameters */
  141. /* Miscellaneous */
  142. static  int abortio;
  143. static  int autoip;
  144. #if UNIX || MAC || NEXT
  145. strlwr( dp )
  146. char *dp;
  147. {
  148.     int   c;
  149.  
  150.     for( ; (c = *dp) != 0; dp++ ) {
  151.   if ( 'A' <= c && c <= 'Z' ) *dp = c - 'A' + 'a';
  152.     }
  153. }
  154. #endif
  155.  
  156.  
  157. #ifdef DLC
  158. /* --- prototypes --- */
  159.   SetUpGrids( );
  160.   DispGrid( GRID * );
  161.   VOID DispPattern( GRID * );         /* changed type to VOID;4-28-93 mjs */
  162.   VOID Sketch( GRID * );              /* changed type to VOID;4-28-93 mjs */
  163.   DrawPixel( GRID *, int, int, int );
  164.   FillPosArr(  );
  165.   ReadFData( );
  166.   WriteFData( );
  167.   Shuffle( int );
  168. #endif
  169.  
  170. SetUpGrids( ) /* Set grids and grid window positions */
  171. {
  172.   int gridwidth[2];
  173.   int inbetween;
  174.   int wx;
  175.   
  176.   if ( BamFlag ) inbetween = 20;
  177.   else inbetween = 0;
  178.   
  179.   gridwidth[0] = gridwidth[1] = 0;
  180.   /* Set up grid parameters */
  181.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  182.     ip_grid[wx].gr_data = wx ? &fdata[n_inputs[0]] : fdata;
  183.     ip_grid[wx].gr_key = wx+1;
  184.     ip_grid[wx].gr_flag = 0;
  185.     ip_grid[wx].gr_xoff = ip_grid[wx].gr_yoff = 0;
  186.     ip_grid[wx].gr_nx = n_across[wx];
  187.     ip_grid[wx].gr_ny = n_down[wx];
  188.     /* Bigger grid => smaller pixels: */
  189.     ip_grid[wx].gr_pxx = 20 - ( n_across[wx] + n_down[wx] ) / 4;
  190.     if ( ip_grid[wx].gr_pxx < 1 ) ip_grid[wx].gr_pxx = 1;
  191.     ip_grid[wx].gr_pxy = ip_grid[wx].gr_pxx;
  192.     gridwidth[wx] =
  193.       ip_grid[wx].gr_nx * (ip_grid[wx].gr_pxx+1) + 1;
  194.   }
  195.   /* Now calculate positions of grid windows */
  196.   wxstrt[0] =
  197.     ( xsize - gridwidth[0] - gridwidth[1] - inbetween ) / 2 ;
  198.   wystrt[0] = ( ysize - (ip_grid[0].gr_ny * (ip_grid[0].gr_pxy+1) + 1) ) / 2 ;
  199.   if (BamFlag) {
  200.     wxstrt[1] = wxstrt[0] + gridwidth[0] + inbetween;
  201.     wystrt[1] = wystrt[0];
  202.   }
  203.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  204.     wxend[wx] = wxstrt[wx] + gridwidth[wx] - 1;
  205.     wyend[wx] = wystrt[wx] + ip_grid[wx].gr_ny * (ip_grid[wx].gr_pxy+1);
  206.     ug_window( ip_grid[wx].gr_key, ip_grid[wx].gr_color[GR_OFF],
  207.          wxstrt[wx], wystrt[wx], wxend[wx], wyend[wx] );
  208.   }
  209. }
  210.  
  211. DispGrid( gridp )
  212. GRID  *gridp;   /* pointer to grid structure */
  213. {
  214.   int wx;   /* work index */
  215.   int x0,y0,x1,y1;  /* endpoints of gridlines */
  216.   
  217.   /* Draw vertical gridlines */
  218.   x1 = x0 = gridp->gr_xoff;
  219.   y0 = gridp->gr_yoff;
  220.   y1 = y0 + gridp->gr_ny * ( gridp->gr_pxy + 1 );
  221.   
  222.   for (wx = 0; wx <= gridp->gr_nx; wx++, x1 = x0 += gridp->gr_pxx + 1 )
  223.     ug_line( gridp->gr_key, gridp->gr_color[GR_LINE], 0, x0, y0, x1, y1, 0 );
  224.  
  225.   /* Draw horizontal gridlines */
  226.   x0 = gridp->gr_xoff;
  227.   x1 = x0 + gridp->gr_nx * ( gridp->gr_pxx + 1 );
  228.   y1 = y0 = gridp->gr_yoff;
  229.   
  230.   for (wx = 0; wx <= gridp->gr_ny; wx++, y1 = y0 += gridp->gr_pxy + 1 )
  231.     ug_line( gridp->gr_key, gridp->gr_color[GR_LINE], 0, x0, y0, x1, y1, 0 );
  232. }
  233.  
  234. /* changed type to VOID; 4-28-93 mjs */
  235. VOID DispPattern( gridp )
  236. GRID  *gridp;   /* Pointer to grid structure */
  237. {
  238.   int wx, wy, wz; /* work indices */
  239.   float *dp;    /* pointer to data */
  240.  
  241.   dp = &gridp->gr_data[0];
  242.   if ( dp == ( float * )0 ) return;
  243.   
  244.   for ( wy = gridp->gr_ny, wz = 0; --wy >= 0 ; )
  245.     for ( wx = 0; wx < gridp->gr_nx; wx++, wz++ )
  246.       DrawPixel( gridp, wx, wy,
  247.            gridp->gr_color[ dp[wz]>0.0001 ? GR_ON : GR_OFF ] );
  248. }
  249.  
  250.  
  251. /* changed type to VOID; 4-28-93 mjs */
  252. VOID Sketch( gridp )
  253. GRID  *gridp;   /* Pointer to grid structure */
  254. {
  255.   int x0, y0, x1, y1;   /* Grid boundary */
  256.   int wx, wy, wz;   /* work indices */
  257.   int key, xp, yp, button;  /* mouse parameters */
  258.   float *dp;      /* pointer to data */
  259.   
  260.   dp = &gridp->gr_data[0];
  261.   if ( dp == ( float * )0 ) return;
  262.   x0 = gridp->gr_xoff;
  263.   y0 = gridp->gr_yoff;
  264.   x1 = x0 + gridp->gr_nx * ( gridp->gr_pxx + 1 );
  265.   y1 = y0 + gridp->gr_ny * ( gridp->gr_pxy + 1 );
  266.  
  267.   for (;;) {
  268.     ug_mouse( &key, &xp, &yp, &button );
  269.     if ( key != gridp->gr_key || xp < x0 || xp >= x1 || yp < y0 || yp >= y1 )
  270.       return;
  271.     if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  272.       /* Calculate grid coordinate */
  273.       wx = ( xp - x0 ) / ( gridp->gr_pxx + 1 );
  274.       wy = ( yp - y0 ) / ( gridp->gr_pxy + 1 );
  275.       DrawPixel( gridp, wx, wy,
  276.            gridp->gr_color[ button == MBUT_LEFT ? GR_ON : GR_OFF ] );
  277.       /* Modify data array */
  278.       wz = (gridp->gr_ny - wy - 1) * gridp->gr_nx + wx;
  279.       dp[wz] = button == MBUT_LEFT ? 1.0 : -1.0;
  280.     }
  281.   }
  282. }
  283.  
  284. DrawPixel( gridp, x, y, color )
  285. GRID  *gridp;   /* pointer to grid structure */
  286. int  x, y;    /* grid coordinate */
  287. int  color;   /* pixel color */
  288. {
  289.       int xstrt, ystrt;
  290.  
  291.       xstrt = gridp->gr_xoff + 1 + ( gridp->gr_pxx + 1 ) * x;
  292.       ystrt = gridp->gr_yoff + 1 + ( gridp->gr_pxy + 1 ) * y;
  293.       ug_boxf( gridp->gr_key, color, 0, xstrt, ystrt,
  294.          xstrt + gridp->gr_pxx - 1, ystrt + gridp->gr_pxy - 1 );
  295. }
  296.  
  297. /* NOTE: following routine will not cope with
  298.    general format ".nna" files. In particular, it
  299.    is assumed that any new line which does not
  300.    start with a continuation character ('&') or
  301.    a comment character ('!') is the start of a
  302.    non-empty record; it is also assumed that there
  303.    are no comments in the middle of records */
  304.  
  305. FillPosArr( )
  306. {
  307.   int wx;   /* work index */
  308.   int ch;   /* Character */
  309.   long  fpos;   /* File position */
  310.   int ftt;    /* First time through */
  311.  
  312.   fseek( fp, 0l, 0 );     /* beginning of file */
  313.   for ( wx = 0; wx < MAX_N_PATTERNS; ) {
  314.     if ( (ch=fgetc( fp )) != '!' && ch != '&' ) {
  315.       ungetc( ch, fp );
  316.       fpos = ftell( fp );
  317.       ftt = 1;
  318.     } else ftt = 0;
  319.     /* Make sure there is something on the line;
  320.        scan to end of line */
  321.     while ( (ch=fgetc( fp)) != NEW_LINE ) {
  322.       if ( ftt && ch >= (int)'0' ) {
  323.   filepos[wx++] = fpos;
  324.   ftt = 0;
  325.       }
  326.       if ( ch == EOF ) return( wx );
  327.     }
  328.   }
  329. }
  330.  
  331. ReadFData( flag )
  332. int flag;   /* Whether or not desired output should be read */
  333. {
  334.   int wx, wy;   /* work index */
  335.   int ch;
  336.   float *dp;    /* data pointer */
  337.  
  338.   if ( curr_pattern < 0 ) curr_pattern = 0;
  339.  
  340.   if ( curr_pattern >= n_patterns ) { /* Don't read from file */
  341.     for ( wx = 0; wx < tot_n_inputs; wx++ )
  342.       fdata[wx] = -1.0;
  343.     curr_pattern = n_patterns;
  344.   } else {
  345.     fseek( fp, filepos[curr_pattern], 0 );
  346.     /* NOTE: Following code assumes data has been written using
  347.        format of WriteFData( ) routine */
  348.     for (wx = 0, wy = 18, dp = fdata; wx < tot_n_inputs;
  349.    wx++, wy--, dp++ ) {
  350.       if ( wy == 0 ) {  /* Look for continuation */
  351.   while ( (ch=fgetc( fp)) != NEW_LINE )
  352.     if ( ch == EOF ) goto bad_return;
  353.   if ( fgetc( fp ) != '&' ) goto bad_return;
  354.   wy = 18;
  355.       }
  356.       if ( fscanf( fp, "%f", dp ) <= 0 ) goto bad_return;
  357.     }
  358.   }
  359.   return( 0 );
  360.  
  361. bad_return:
  362.   PutStr( "Bad file format\n" );
  363.   return( -1 );
  364. }
  365.  
  366. WriteFData( flag )
  367. int flag;   /* Whether or not desired output should be written */
  368. {
  369.   int wx, wy;   /* work indices */
  370.  
  371.   if ( curr_pattern < 0 ) curr_pattern = 0;
  372.  
  373.   if ( curr_pattern >= n_patterns ) {
  374.     curr_pattern = n_patterns;
  375.     n_patterns++;
  376.     fseek( fp, 0l, 2 );     /* Seek End of File */
  377.     filepos[curr_pattern] = ftell( fp );
  378.   }
  379.  
  380.   fseek( fp, filepos[curr_pattern], 0 );
  381.  
  382.   fputc( ' ', fp );
  383.   for ( wx = 0, wy = 18; wx < tot_n_inputs; wx++, wy-- ) {
  384.     if ( wy == 0 ) {
  385.       fputc( NEW_LINE, fp );
  386.       fputc( '&' , fp );    /* Continuation line */
  387.       wy = 18;
  388.     }
  389.     fprintf( fp, " %2.0f.", fdata[wx] );
  390.   }
  391.   fputc( NEW_LINE, fp );
  392.   curr_pattern++;
  393. }
  394.  
  395. Shuffle( size )
  396. int size;
  397. {
  398.   int wx, wy, wz; 
  399.   int swap;
  400.  
  401.   for ( wx = 0, wy = size; wx < size; wx++, wy-- ) {
  402.     wz = rand( ) % wy;
  403.     swap = shuffle_array[wx];
  404.     shuffle_array[wx] = shuffle_array[wx + wz];
  405.     shuffle_array[wx + wz] = swap;
  406.   }
  407. }
  408.  
  409. /************************************************************************
  410.  *
  411.  *  UsrIO - user I/O routine to handle requests from NWORKS
  412.  *
  413.  ************************************************************************
  414.  */
  415. static int InitFlag = 0;    /* initialize things flag */
  416. void UsrIO()     /* handle NWORKS requests */
  417. {
  418.     int   key, xp, yp, button;      /* mouse interface */
  419.     int   newfile;
  420.     int   wx;       /* work index */
  421.     GMENU_ITEM  *gmip;
  422.     char  sbuf[60], *sp;      /* work string and pointer */
  423.     if ( InitFlag == 0 ) {
  424.     
  425.     AIOMenu.item = PMenuList;
  426.     LrnMenu.item = PMenuList;
  427.     PMenuList[0].text = "Scroll";
  428.     PMenuList[1].text = "Rewind";
  429.     PMenuList[2].text = "Enter";
  430.     PMenuList[3].text = "Quit";
  431.     PMenuList[4].text = "Auto";
  432.  
  433.  
  434.     if ((filepos=(long *)malloc(MAX_N_PATTERNS*sizeof(long)))
  435.           == (long *)0 ||
  436.       (shuffle_array=(int *)malloc(MAX_N_PATTERNS*sizeof(int)))
  437.           == (int *)0 ||
  438.       (fdata=(float *)malloc(2*N_ACR_MAX*N_DWN_MAX*sizeof(float)))
  439.           == (float *)0 ) {
  440.       PutStr("Not Enough memory to run pattern\n");
  441.       IORTNCDE = -1;
  442.       return;
  443.     }
  444.     
  445.   /* Get screen parameters */
  446.   ug_gparms( &xsize, &ysize, &ncolor, &chrx, &chry);
  447.   
  448.   if ( ncolor < 8 ) {
  449.     gm_intcolor = 1;
  450.     gm_txtcolor = 0;
  451.     gm_outcolor = 0;
  452.   } else {
  453.     gm_intcolor = 7;
  454.     gm_txtcolor = 4;
  455.     gm_outcolor = 0;
  456.   }
  457.     
  458.   for ( wx=0; wx<2; wx++ ) {
  459.     ip_grid[wx].gr_color[GR_OFF]  = gm_intcolor;
  460.     ip_grid[wx].gr_color[GR_ON]   = gm_txtcolor;
  461.     ip_grid[wx].gr_color[GR_LINE] = gm_txtcolor;
  462.   }
  463.  
  464.   InitGMenu( &AIOMenu, chrx, chry );
  465.   AIOMenu.x0 = 0; /* Menu position relative to window */
  466.   AIOMenu.y0 = 0;
  467.  
  468.   InitGMenu( &LrnMenu, chrx, chry );
  469.   LrnMenu.x0 = 0; /* Menu position relative to window */
  470.   LrnMenu.y0 = 0;
  471.  
  472.   ug_rdnetinf( &nlayp, &ninp, &noutp, <ype, &csp, &netnp );
  473.   strncpy( filenroot, netnp, 8 ); /* Read network name */
  474.   filenroot[8] = '\0';
  475.   strncpy( sbuf, csp, 3 ); /* Get first 3 letters of control strategy */
  476.   sbuf[3] = '\0';
  477.   strlwr( sbuf );   /* convert to lower case */
  478.   /* See if BAM control strategy - this will require 2 input grids */
  479.   if ( strcmp( sbuf, "bam" ) == 0 ) BamFlag = 1;
  480.   else BamFlag = 0;
  481.   InitFlag = 1;
  482.     }
  483.  
  484.     IORTNCDE = 0;       /* good return for data */
  485.     switch( IOREQCDE ) {
  486.  
  487.     case RQ_ATTENTION:
  488.       if ( fp != (FILE *) 0 ) fclose( fp );
  489.  
  490.       sprintf( sbuf,
  491.          "Enter name of pattern file ( default: %s ):", filenroot );
  492.       PutStr( sbuf );
  493.       sp = GetStr( );
  494.       PutStr("\n");
  495.       if ( strcmp( sp, "" ) != 0 ) strncpy( filenroot, sp, 9 );
  496.       strcpy( filename, filenroot );
  497.       strcat( filename, ".nna" );
  498.       if ( (fp = fopen( filename, "r" )) == (FILE *)0 )
  499.   {
  500.     newfile = 1;
  501.   }
  502.       else
  503.   {
  504.     newfile = 0;
  505.     fclose(fp);
  506.   }
  507.       
  508.       if ( ( fp = fopen( filename, "a+" ) ) == (FILE *)0 ) {
  509.   sprintf( sbuf, "Cannot open file <%s>\n", filename );
  510.   PutStr( sbuf );
  511.   goto aio_return;
  512.       }
  513.  
  514.       fseek( fp, 0l, 0 );
  515.       if ( newfile ) {      /* New file */
  516.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  517.     strcpy( sbuf, "Enter number of pixels across" );
  518.     if ( wx == 1 ) strcat( sbuf, " for second grid:" );
  519.     else strcat( sbuf, ":" );
  520.     PutStr( sbuf );
  521.     sp = GetStr( );
  522.     PutStr("\n");
  523.     sscanf( sp, "%ld", &n_across[wx] );
  524.     if ( n_across[wx] < N_ACR_MIN ) n_across[wx] = N_ACR_MIN;
  525.     if ( n_across[wx] > N_ACR_MAX ) n_across[wx] = N_ACR_MAX;
  526.     PutStr( "Enter number of pixels down:" );
  527.     sp = GetStr( );
  528.     PutStr("\n");
  529.     sscanf( sp, "%ld", &n_down[wx] );
  530.     if ( n_down[wx] < N_DWN_MIN ) n_down[wx] = N_DWN_MIN;
  531.     if ( n_down[wx] > N_DWN_MAX ) n_down[wx] = N_DWN_MAX;
  532.     fprintf( fp,
  533.       "! number of pixels across = %2ld, number of pixels down = %2ld%s",
  534.       n_across[wx], n_down[wx], NEW_LINE_STR );
  535.   }
  536.       } else {
  537.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  538.     if ( fgets( fbuf, MAX_STR, fp ) == 0 ) goto aio_read_error;
  539.     sscanf( fbuf,
  540.       "! number of pixels across = %ld, number of pixels down = %ld",
  541.       &n_across[wx], &n_down[wx] );
  542.     if ( n_across[wx] < N_ACR_MIN || n_across[wx] > N_ACR_MAX ||
  543.          n_down[wx]   < N_DWN_MIN || n_down[wx]   > N_DWN_MAX ) {
  544.       PutStr( "Unexpected values in file\n" );
  545.       goto aio_return;
  546.           }
  547.   }
  548.       }
  549.       tot_n_inputs = 0;
  550.       for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  551.   n_inputs[wx] = n_across[wx] * n_down[wx];
  552.   tot_n_inputs += n_inputs[wx];
  553.       }
  554.      
  555.       SetUpGrids( );  /* Set up grid parameters and grid window positions */
  556.  
  557.       /* Set up menu and menu window */
  558.       AIOMenu.key = 3;
  559.       wxstrt[2] = ( xsize - AIOMenu.x1 ) / 2;
  560.       wxend[2] = wxstrt[2] + AIOMenu.x1 + 2;
  561.       wystrt[2] = ( wystrt[0] - AIOMenu.y1 ) / 2;
  562.       wyend[2] = wystrt[2] + AIOMenu.y1 + 2;
  563.       ug_window( AIOMenu.key, ip_grid[wx].gr_color[GR_OFF],
  564.            wxstrt[2], wystrt[2], wxend[2], wyend[2] );
  565.  
  566.       n_patterns = FillPosArr(  );  /* Fill Position array */
  567.       curr_pattern = n_patterns;  /* End of file */
  568.       ReadFData( 0 );     /* Special eof case */
  569.  
  570.       /* Display everything */
  571.       for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  572.   DispGrid( &ip_grid[wx] );
  573.         DispPattern( &ip_grid[wx] );
  574.       }
  575.       for (gmip = AIOMenu.item, wx = 0; wx < AIOMenu.num_items;
  576.           gmip++, wx++ )
  577.   gmip->flag &= ~GM_LOCKED;
  578.       DispGMenu( &AIOMenu );
  579.  
  580.       for ( ; ; ) {
  581.         while ( ( gmip=LookGMenu(&AIOMenu,&button) ) != (GMENU_ITEM *) 0 ) {
  582.     switch( gmip->code ) {
  583.       case CR_SCROLL:
  584.         if ( button == MBUT_LEFT )  {   /* Scroll down */
  585.     curr_pattern++;
  586.     if ( ReadFData( 0 ) < 0 ) goto aio_return;
  587.     for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  588.             DispPattern( &ip_grid[wx] );
  589.         }
  590.         if ( button == MBUT_RIGHT ) {   /* Scroll up */
  591.     curr_pattern--;
  592.     if ( ReadFData( 0 ) < 0 ) goto aio_return;
  593.     for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  594.             DispPattern( &ip_grid[wx] );
  595.         }
  596.         break;
  597.       case CR_SEEK:
  598.         if ( button == MBUT_LEFT ) {  /* Start of file data */
  599.     curr_pattern = 0;
  600.     if ( ReadFData( 0 ) < 0 ) goto aio_return;
  601.     for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  602.       DispPattern( &ip_grid[wx] );
  603.         }
  604.         if ( button == MBUT_RIGHT ) {   /* End of file data */
  605.     curr_pattern = n_patterns;
  606.     if ( ReadFData( 0 ) < 0 ) goto aio_return;
  607.     for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  608.       DispPattern( &ip_grid[wx] );
  609.         }
  610.               break;
  611.       case CR_ENTER:
  612.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  613.           WriteFData( 0 );
  614.     ReadFData( 0 );
  615.     for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  616.       DispPattern( &ip_grid[wx] );
  617.         }
  618.         break;
  619.       case CR_QUIT:
  620.         if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  621.           IORTNCDE = -1;
  622.     goto aio_return;
  623.         }
  624.         break;
  625.     }
  626.     /* If button was pressed, wait for it to be released */
  627.     while ( button != 0 )
  628.       ug_mouse( &key, &xp, &yp, &button );
  629.         }
  630.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  631.     Sketch( &ip_grid[wx] );
  632.       }
  633.  
  634. aio_read_error:
  635.       sprintf( sbuf, "Error reading file <%s>\n", filename );
  636.       PutStr( sbuf );
  637.  
  638. aio_return:
  639.       if ( fp != (FILE *)0 ) fclose( fp );
  640.       fp = (FILE *)0;
  641.       for ( wx = 1; wx < 4; wx++ ) ug_windel( wx );
  642.       IORTNCDE = 1;
  643.       break;
  644.  
  645.       
  646.     case RQ_REWIND:       /* rewind the input file */
  647.  
  648.       if ( fp != (FILE *)0 ) fseek( fp, 0l, 0 );
  649.       break;
  650.  
  651.       
  652.     case RQ_LSTART:       /* starting learn */
  653.     case RQ_RSTART:       /* starting recall */
  654.      abortio = 0;       /* abort flag */
  655.       autoip = 0;       /* Assume hand input */
  656.       if ( fp == (FILE *)0 ) {      /* Not yet opened */
  657.         sprintf( sbuf,
  658.            "Enter name of pattern file ( default: %s ):", filenroot );
  659.         PutStr( sbuf );
  660.   sp = GetStr( );
  661.   PutStr("\n");
  662.   if ( strcmp( sp, "" ) != 0 ) strncpy( filenroot, sp, 9 );
  663.   strcpy( filename, filenroot );
  664.   strcat( filename, ".nna" );
  665.         if ( ( fp = fopen( filename, "r" ) ) == (FILE *)0 ) {
  666.     sprintf( sbuf, "Cannot open file <%s>; learn aborted\n", filename );
  667.     PutStr( sbuf );
  668.     abortio = 1;
  669.     goto lrns_return;
  670.         }
  671.   shufflex = 0;
  672.   /* Initialize shuffle array */
  673.         for ( wx = 0; wx < MAX_N_PATTERNS; wx++ )
  674.           shuffle_array[ wx ] = wx;
  675.  
  676.   n_patterns = FillPosArr(  );    /* Fill Position array */
  677.   curr_pattern = 0;     /* Start of of file */
  678.       }
  679.  
  680.       fseek( fp, 0l, 0 );     /* rewind */
  681.  
  682.       for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  683.   if ( fgets( fbuf, MAX_STR, fp ) == 0 ) {
  684.           PutStr( "Read error; learn aborted\n" );
  685.           abortio = 1;
  686.           goto lrns_return;
  687.         }
  688.   sscanf( fbuf,
  689.           "! number of pixels across = %ld, number of pixels down = %ld",
  690.           &n_across[wx], &n_down[wx] );
  691.   if ( n_across[wx] < N_ACR_MIN || n_across[wx] > N_ACR_MAX ||
  692.        n_down[wx]   < N_DWN_MIN || n_down[wx]   > N_DWN_MAX ) {
  693.     PutStr( "Unexpected values in file; learn aborted\n" );
  694.     abortio = 1;      /* Abort */
  695.     goto lrns_return;
  696.         }
  697.       }
  698.       tot_n_inputs = 0;
  699.       for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  700.   n_inputs[wx] = n_across[wx] * n_down[wx];
  701.   tot_n_inputs += n_inputs[wx];
  702.       }
  703.       if ( tot_n_inputs != ninp ) {
  704.   PutStr( "Data incompatible with network; learn aborted\n" );
  705.         abortio = 1;
  706.         goto lrns_return;
  707.       }
  708.       
  709.       SetUpGrids( );  /* Set up grid parameters and grid window positions */
  710.  
  711.       /* Set up menu and menu window */
  712.       LrnMenu.key = 3;
  713.       wxstrt[2] = ( xsize - LrnMenu.x1 ) / 2;
  714.       wxend[2] = wxstrt[2] + LrnMenu.x1 + 2;
  715.       wystrt[2] = ( wystrt[0] - LrnMenu.y1 ) / 2;
  716.       wyend[2] = wystrt[2] + LrnMenu.y1 + 2;
  717.       ug_window( LrnMenu.key, gm_intcolor,
  718.            wxstrt[2], wystrt[2], wxend[2], wyend[2] );
  719.  
  720. lrns_return:
  721.       if ( abortio ) {
  722.   if ( fp != (FILE *)0 ) fclose( fp );
  723.   fp = (FILE *)0;
  724.   for ( wx = 1; wx < 4; wx++ ) ug_windel( wx );
  725.       }
  726.       break;
  727.       
  728.     case RQ_LEARNIN:        /* read training input */
  729.     case RQ_READ:       /* read test data */
  730.  
  731.       if ( abortio ) goto lrnin_return;
  732.       
  733.       if ( IOLAYER != 0 ) {
  734.   PutStr( "This UserIO program expects data only at the input buffer.\n" );
  735.   PutStr( "You may be using an out-dated control strategy\n" );
  736.   abortio = 1;
  737.   goto lrnin_return;
  738.       }
  739.  
  740.       if ( !autoip ) {
  741.   if ( ReadFData( 0 ) < 0 ) goto lrnin_return;
  742.   for (gmip = LrnMenu.item, wx = 0; wx < LrnMenu.num_items;
  743.           gmip++, wx++ )
  744.     gmip->flag &= ~GM_LOCKED;
  745.   ug_winclr( LrnMenu.key );
  746.   DispGMenu( &LrnMenu );
  747.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ ) {
  748.     DispGrid( &ip_grid[wx] );
  749.     DispPattern( &ip_grid[wx] );
  750.   }
  751.         for ( ; ; ) {
  752.           while ( (gmip=LookGMenu(&LrnMenu,&button)) != (GMENU_ITEM *) 0 ) {
  753.       switch( gmip->code ) {
  754.           case CR_SCROLL:
  755.             if ( button == MBUT_LEFT )  { /* Scroll down */
  756.         curr_pattern++;
  757.         if ( ReadFData( 0 ) < 0 ) goto lrnin_return;
  758.         for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  759.           DispPattern( &ip_grid[wx] );
  760.             }
  761.             if ( button == MBUT_RIGHT ) {   /* Scroll up */
  762.         curr_pattern--;
  763.         if ( ReadFData( 0 ) < 0 ) goto lrnin_return;
  764.         for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  765.           DispPattern( &ip_grid[wx] );
  766.       }
  767.       break;
  768.           case CR_SEEK:
  769.             if ( button == MBUT_LEFT ) {  /* Start of file data */
  770.         curr_pattern = 0;
  771.         if ( ReadFData( 0 ) < 0 ) goto lrnin_return;
  772.         for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  773.           DispPattern( &ip_grid[wx] );
  774.             }
  775.             if ( button == MBUT_RIGHT ) {   /* End of file data */
  776.         curr_pattern = n_patterns;
  777.         if ( ReadFData( 0 ) < 0 ) goto lrnin_return;
  778.         for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  779.           DispPattern( &ip_grid[wx] );
  780.             }
  781.                   break;
  782.     case CR_ENTER:
  783.             if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  784.         memcpy( IODATA, fdata, IOCOUNT*sizeof( float ) );
  785.         curr_pattern++;
  786.         goto lrnin_return;
  787.             }
  788.             break;
  789.           case CR_QUIT:
  790.             if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  791.               IORTNCDE = -1;
  792.         goto lrnin_return;
  793.             }
  794.             break;
  795.           case CR_AUTO:
  796.             if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  797.         autoip = 1;
  798.         goto auto_lrn;
  799.       }
  800.       break;
  801.       }
  802.       /* If button was pressed, wait for it to be released */
  803.       while ( button != 0 )
  804.         ug_mouse( &key, &xp, &yp, &button );
  805.     }
  806.     for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  807.       Sketch( &ip_grid[wx] );
  808.         }
  809.       } else {      /* Auto input */
  810. auto_lrn:
  811.   for (gmip = LrnMenu.item, wx = 0; wx < LrnMenu.num_items;
  812.           gmip++, wx++ )
  813.     gmip->flag &= ~GM_LOCKED;
  814.   ug_winclr( LrnMenu.key );
  815.   DispGMenu( &LrnMenu );
  816.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  817.     DispGrid( &ip_grid[wx] );
  818.         if ( shufflex == 0 ) Shuffle( n_patterns );
  819.   curr_pattern = shuffle_array[ shufflex++ ];
  820.   if ( ReadFData( 0 ) < 0 ) {
  821.     PutStr( "Error reading file; learn aborted\n" );
  822.     abortio = 1;
  823.     goto lrnin_return;
  824.   }
  825.   if ( shufflex >= n_patterns ) shufflex = 0;
  826.   memcpy( IODATA, fdata, IOCOUNT * sizeof( float ) );
  827.   for ( wx = 0; wx < ( BamFlag ? 2 : 1 ); wx++ )
  828.     DispPattern( &ip_grid[wx] );
  829.       }
  830.  
  831. lrnin_return:
  832.       if ( abortio ) {
  833.   if ( fp != (FILE *)0 ) fclose( fp );
  834.   fp = (FILE *)0;
  835.   for ( wx = 1; wx < 4; wx++ ) ug_windel( wx );
  836.   IORTNCDE = -1;
  837.       }
  838.       break;
  839.  
  840.     case RQ_WRSTEP:       /* write interim results */
  841.       if ( abortio ) goto wrstep_return;
  842.  
  843.       if ( BamFlag ) wx = ( IOLAYER == 1 ? 0 : 1 );
  844.       else wx = 0;
  845.       DispGrid( &ip_grid[wx] );
  846. /* add size_t cast for MS-C 7.0; 4-28-93 mjs */
  847. #ifdef MSC
  848.       memcpy( ip_grid[wx].gr_data, IODATA, 
  849.               (size_t)(n_inputs[wx]*sizeof( float )) );
  850. #else
  851.       memcpy( ip_grid[wx].gr_data, IODATA, n_inputs[wx]*sizeof( float ) );
  852. #endif
  853.       DispPattern( &ip_grid[wx] );
  854.  
  855.       if ( !autoip ) {
  856.   for ( ; ; ) {
  857.     PMenuList[CR_SCROLL].flag |= GM_LOCKED;
  858.     PMenuList[CR_SEEK].flag |= GM_LOCKED;
  859.     PMenuList[CR_AUTO].flag |= GM_LOCKED;
  860.     ug_winclr( LrnMenu.key );
  861.     DispGMenu( &LrnMenu );
  862.  
  863.     PutStr(
  864.       "ENTER for next iteration, QUIT to end current recall \n");
  865.     for ( ; ; ) {
  866.       while ( (gmip=LookGMenu(&LrnMenu,&button))==(GMENU_ITEM *) 0) ;
  867.       switch( gmip->code ) {
  868.         case CR_ENTER:
  869.             if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  870.       goto wrstep_return;
  871.     }
  872.     break;
  873.         case CR_QUIT:
  874.             if ( button == MBUT_LEFT || button == MBUT_RIGHT ) {
  875.       IORTNCDE = -1;
  876.       goto wrstep_return;
  877.     }
  878.     break;
  879.         }
  880.       }
  881.     }
  882.   }
  883. wrstep_return:
  884.       if ( abortio ) {
  885.   if ( fp != (FILE *)0 ) fclose( fp );
  886.   fp = (FILE *)0;
  887.   for ( wx = 1; wx < 4; wx++ ) ug_windel( wx );
  888.   IORTNCDE = -1;
  889.       }
  890.       break;
  891.  
  892.  
  893.     case RQ_LEARNOUT:       /* read desired output */
  894.   /* IODATA points to an empty array of IOCOUNT values.  The
  895.      elements of the array will become the desired outputs for
  896.      training purposes.  These desired outputs correspond to
  897.      the most recent "RQ_LEARNIN" request.
  898.   */
  899.     case RQ_RCLTST:   /* read desired output during recall test */
  900.   /* IODATA points to an empty array of IOCOUNT values.  The
  901.      elements of the array will become the desired outputs for
  902.      recall purposes.  This request is only made during a
  903.      Execute Network/Recall Test.
  904.   */
  905.   break;
  906.  
  907.  
  908.     case RQ_LEARNRSLT:
  909.     case RQ_WRITE:        /* write out results */
  910.   if ( abortio ) goto write_return;
  911.   if ( !autoip ) {
  912.     PutStr(
  913.     "Cycle complete; press left or right mouse button to continue.\n");
  914.     for ( ; ; ) {
  915.       ug_mouse( &key, &xp, &yp, &button ); /* wait for mouse */
  916.       if (button == MBUT_LEFT || button == MBUT_RIGHT) break;
  917.     }
  918.   }
  919.  
  920. write_return:
  921.       if ( abortio ) {
  922.   if ( fp != (FILE *)0 ) fclose( fp );
  923.   fp = (FILE *)0;
  924.   for ( wx = 1; wx < 4; wx++ ) ug_windel( wx );
  925.   IORTNCDE = -1;
  926.       }
  927.   break;
  928.  
  929.     case RQ_TERM:       /* terminate interface */
  930.   /* close any files which may be open.  Deallocate any memory
  931.      which was allocated.  (This is VERY VERY important.  If
  932.      allocated memory is NOT released, dos memory will become
  933.      fragmented and it will become necessary to reboot.
  934.   */
  935. #if 1 
  936.   free((void *)filepos);
  937.   free((void *)shuffle_array);
  938.   free((void *)fdata);
  939. #else
  940.   free(filepos);
  941.   free(shuffle_array);
  942.   free(fdata);
  943. #endif
  944.   if ( fp != (FILE *)0 ) fclose( fp );
  945.   fp = (FILE *)0;
  946.   break;
  947.     }
  948.  
  949.     return;
  950. }
  951.